/**
* <copyright>
*
* Copyright (c) 2002-2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
*
* </copyright>
*
* $Id: RoseEcoreBuilder.java,v 1.21 2008/12/22 14:26:15 emerks Exp $
*/
package com.sap.emf.importer.moin.rose.builder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelPackage;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreSwitch;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.impl.EMOFExtendedMetaData;
import com.sap.emf.importer.moin.rose.RoseImporterPlugin;
import com.sap.emf.importer.moin.rose.parser.RoseNode;
import com.sap.emf.importer.moin.rose.parser.Util;
/**
* Traverses the Rose file and create eCore object in memory.
*/
public class RoseEcoreBuilder implements RoseVisitor
{
private static final String SAP2MOF_OPERATION_CODE_OCL = "\"sap2mof.OperationCodeOcl\"";
private static final String UML2MOF_CLUSTERED_IMPORT = "\"uml2mof.clusteredImport\"";
private static final String ROSE2MOF_CONSTRAINED_ELEMENTS = "\"rose2mof.constrainedElements\"";
private static final String ROSE2MOF_RETURN_MULTIPLICITY = "rose2mof.return.multiplicity";
private static final String MOF = "\"MOF\"";
private static final String VALIDATION_DELEGATES = "validationDelegates";
private static final String INVOCATION_DELEGATES = "invocationDelegates";
private static final String INV = "inv";
private static final String COLON = ":";
private static final String DELEGATE_URI = "http://www.eclipse.org/emf/2002/Ecore/OCL";
private static final String ECORE_NS_URI = "http://www.eclipse.org/emf/2002/Ecore";
private static final String CONSTRAINTS = "constraints";
//do you want to parse the semantic tab info?
public boolean activateSemanticsTab = false;
class DeferredConstraintAnnotation{
public DeferredConstraintAnnotation(String constraintName, String constraintExpr, String clsName2) {
name=constraintName;
expr=constraintExpr;
clsName= clsName2;
}
String name;
String expr;
String clsName;
}
public boolean noQualify = false;
public boolean unsettablePrimitive = "true".equals(System.getProperty("EMF_UNSETTABLE_PRIMITIVE"));
protected RoseUtil roseUtil;
protected Set<EModelElement> bounded = new HashSet<EModelElement>();
protected Map<EStructuralFeature, String> eStructuralFeatureToXMLNamespaceMap = new HashMap<EStructuralFeature, String>();
protected List<EStructuralFeature> eStructuralFeatures = new BasicEList.FastCompare<EStructuralFeature>();
protected Map<EEnum, String> eEnums = new HashMap<EEnum, String>();
protected Map<String, Object> idToParentMap = new HashMap<String, Object>();
protected EReference ref1 = null;
protected EReference ref2 = null;
protected RoseNode role1 = null;
protected RoseNode role2 = null;
protected EGenericType eGenericType1;
protected EGenericType eGenericType2;
protected Set<EAttribute> attributesToConvert = new HashSet<EAttribute>();
// This could potentially map every created model element to its corresponding Rose node.
// However, for now we're only using it as needed.
//
protected Map<EModelElement, RoseNode> eModelElementToRoseNodeMap = new HashMap<EModelElement, RoseNode>();
private final List<DeferredConstraintAnnotation> deferredConstraints = new ArrayList<RoseEcoreBuilder.DeferredConstraintAnnotation>();
private final List<EClassifier> allClasses = new ArrayList<EClassifier>();
public RoseEcoreBuilder(RoseUtil roseUtil)
{
super();
this.roseUtil = roseUtil;
}
@Override
public void visitList(RoseNode roseNode)
{
// Nothing to do
}
@Override
public void visitObject(RoseNode roseNode)
{
String roseNodeValue = roseNode.getValue();
String objectKey = roseNode.getKey();
String objectType = Util.getType(roseNodeValue);
String objectName = Util.getName(roseNodeValue);
// System.out.println("---> visitObject,,, objectKey - objectType - objectName: " + objKey + ", " + objType + ", " + objectName);
// Get the parent object.
//
RoseNode currentNode = roseNode;
Object parent = currentNode.getNode();
while (parent == null)
{
currentNode = currentNode.getParent();
parent = currentNode.getNode();
}
visitObject(roseNode, roseNodeValue, objectKey, objectType, objectName, parent);
}
protected void visitObject(RoseNode roseNode, String roseNodeValue, String objectKey, String objectType, String objectName, Object parent)
{
if (objectKey.equals("") && objectType.equals(RoseStrings.CLASS_CATEGORY))
{
visitClassCategory(roseNode, roseNodeValue, objectKey, objectName, parent);
}
else if (objectType.equals(RoseStrings.CLASS))
{
if (RoseStrings.CONSTRAINT_STEREOTYPE.equals(roseNode.getStereotype())){
visitConstraintClass(roseNode, roseNodeValue, objectKey, objectName, parent);
}
else{
visitClass(roseNode, roseNodeValue, objectKey, objectName, parent);
}
}
else if (objectType.equals(RoseStrings.OPERATION))
{
visitOperation(roseNode, roseNodeValue, objectKey, objectName, parent);
}
else if (objectType.equals(RoseStrings.PARAMETER))
{
visitParameter(roseNode, roseNodeValue, objectKey, objectName, parent);
}
else if (objectType.equals(RoseStrings.INHERITANCE_RELATIONSHIP))
{
visitInheritanceRelationship(roseNode, roseNodeValue, objectKey, objectName, parent);
}
else if (objectType.equals(RoseStrings.CLASSATTRIBUTE) && (!roseNode.isDerived() || !"reference".equals(roseNode.getStereotype())))
{
visitClassattribute(roseNode, roseNodeValue, objectKey, objectName, parent);
}
else if (objectType.equals(RoseStrings.ASSOCIATION))
{
visitAssociation(roseNode, roseNodeValue, objectKey, objectName, parent);
}
else if (objectType.equals(RoseStrings.ROLE) && !objectName.startsWith("/"))
{
visitRole(roseNode, roseNodeValue, objectKey, objectName, parent);
}
}
protected void visitClassCategory(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
// Map to an EPackage.
//
if (roseNode.isLoaded())
{
String id = roseNode.getRoseId();
if (idToParentMap.containsKey(id))
{
parent = idToParentMap.get(id);
}
EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
addDelegateAnnotation(ePackage);
if (parent instanceof EPackage)
{
// Add to package.
//
((EPackage)parent).getESubpackages().add(ePackage);
}
else if (parent instanceof EList<?>)
{
@SuppressWarnings("unchecked")
EList<Object> list = (EList<Object>)parent;
list.add(ePackage);
}
// add clustered imports
addPackagesFromClusteredImports(roseNode, ePackage, UML2MOF_CLUSTERED_IMPORT);
setEPackageProperties(roseNode, ePackage, objectName.toLowerCase());
}
else
{
idToParentMap.put(roseNode.getRoseId(), parent);
}
}
/**
* @param roseNode
* @param ePackage
* @param property
*/
private void addPackagesFromClusteredImports(RoseNode roseNode, EPackage ePackage, String property) {
for(RoseNode n: roseNode.getNodes()){
if(RoseStrings.ATTRIBUTE_SET.equals(Util.getType(n.getValue()))){
for(RoseNode attr: n.getNodes()){
if(RoseStrings.ATTRIBUTE.equals(Util.getType(attr.getValue()))){
String[] pkgNames = parseAttributesFromNode(attr, property);
if(pkgNames == null) {
continue;
}
for(String pkgName: pkgNames){
EPackage pkg = EcoreFactory.eINSTANCE.createEPackage();
ePackage.getESubpackages().add(pkg);
setEPackageProperties(roseNode, pkg, pkgName);
}
}
}
}
}
}
protected void visitConstraintClass(RoseNode constraintClassRoseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
Util.getName(roseNodeValue);
String constraintName=objectName;
String constraintExpr="";
for(RoseNode n:constraintClassRoseNode.getNodes()){
if(RoseStrings.OPERATIONS.equalsIgnoreCase(Util.getType(n.getValue()))){
for(RoseNode op: n.getNodes()){
if(RoseStrings.OPERATION.equals(Util.getType(op.getValue())) && RoseStrings.OCL_OPERATION.equals(Util.getName(op.getValue()))){
String fullOCLStatement = op.getSemantics();
int invStart= fullOCLStatement.indexOf(INV);
if(invStart!=-1){
int colonStart=fullOCLStatement.indexOf(COLON);
String newConstraintName=fullOCLStatement.substring(invStart+INV.length(),colonStart).trim();
if(!newConstraintName.isEmpty()) {
constraintName=newConstraintName;
}
constraintExpr= fullOCLStatement.substring(colonStart+1).trim();
}else{
constraintExpr= fullOCLStatement;
}
}
}
}
}
if(!(parent instanceof EClassifier)){
if(parent instanceof EPackage){
for(RoseNode n: constraintClassRoseNode.getNodes()){
if(RoseStrings.ATTRIBUTE_SET.equals(Util.getType(n.getValue()))){
for(RoseNode attr: n.getNodes()){
if(RoseStrings.ATTRIBUTE.equals(Util.getType(attr.getValue()))){
String[] clsNames = parseAttributesFromNode(attr, ROSE2MOF_CONSTRAINED_ELEMENTS);
if(clsNames == null) {
continue;
}
for(String clsName: clsNames){
deferredConstraints.add(new DeferredConstraintAnnotation(constraintName, constraintExpr, clsName));
}
}
}
}
}
}
return;
}
EClassifier clazz = (EClassifier) parent;
addConstraintToNamedElement(constraintName, constraintExpr, clazz);
}
private String[] parseAttributesFromNode(RoseNode node, String property){
// there should be exactly 3 columns
if(node.getNodes().size()!=3)
return null;
// first column MOF
String firstAttrValue= node.getNodes().get(0).getValue();
if(!MOF.equals(firstAttrValue))
return null;
//second column should define the given property"
String secondAttrValue= node.getNodes().get(1).getValue();
if(!property.equals(secondAttrValue))
return null;
String thirdAttrValue= Util.getName(node.getNodes().get(2).getNodes().get(0).getValue());
// we have found a constraint
if(thirdAttrValue == null && SAP2MOF_OPERATION_CODE_OCL.equals(property)){
List<RoseNode> nodes = node.getNodes().get(2).getNodes().get(0).getNodes();
String[] forthAttrValue = new String[nodes.size()];
int i = 0;
for(RoseNode n: nodes){
forthAttrValue[i] = n.getValue();
i++;
}
return forthAttrValue;
}
return thirdAttrValue.split(",");
}
public void processDefferendConstraints(){
for(EClassifier cls: allClasses){
for(DeferredConstraintAnnotation anno: deferredConstraints){
if(cls.getName().equals(anno.clsName)){
addConstraintToNamedElement(anno.name, anno.expr, cls);
}
}
}
}
/**
* @param constraintName
* @param constraintExpr
* @param element
*/
private void addConstraintToNamedElement(String constraintName, String constraintExpr, ENamedElement element) {
EcoreUtil.setAnnotation(element, DELEGATE_URI, constraintName, constraintExpr);
String csString=EcoreUtil.getAnnotation(element, ECORE_NS_URI, CONSTRAINTS);
if(csString==null) {
EcoreUtil.setAnnotation(element, ECORE_NS_URI, CONSTRAINTS, constraintName);
} else {
EcoreUtil.setAnnotation(element, ECORE_NS_URI, CONSTRAINTS, csString+" "+constraintName);
}
}
protected void visitClass(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
if (objectName == null || objectName.length() == 0)
{
String quid = roseNode.getRoseId();
if (quid != null)
{
quid = quid.substring(1, quid.length() - 1);
}
objectName = "Unnamed" + quid;
error(RoseImporterPlugin.INSTANCE.getString("_UI_UnnamedClass_message", new Object []{ objectName }));
}
// Map to EClass, EEnum or EInerface.
// Note that we do not map structure and primitive type class.
//
RoseNode stereoTypeNode = roseNode.findNodeWithKey(RoseStrings.STEREOTYPE);
if (stereoTypeNode != null)
{
String stereoTypeValue = stereoTypeNode.getValue();
stereoTypeValue = stereoTypeValue.substring(1, stereoTypeValue.length() - 1);
if (stereoTypeValue.equals(RoseStrings.INTERFACE))
{
// Map to an EClass.
//
EClass eClass = EcoreFactory.eINSTANCE.createEClass();
allClasses.add(eClass);
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
classifierName = validName(upperCaseName(objectName));
}
eClass.setName(classifierName);
roseNode.setNode(eClass);
setEClassProperties(roseNode, eClass);
eClass.setInterface(true);
eClass.setAbstract(true);
build(roseNode, parent, eClass);
}
else if (stereoTypeValue.equalsIgnoreCase(RoseStrings.ENUMERATION))
{
// Map to an EEnum.
EEnum eEnum = EcoreFactory.eINSTANCE.createEEnum();
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
classifierName = validName(upperCaseName(objectName));
}
eEnum.setName(classifierName);
roseNode.setNode(eEnum);
setEEnumProperties(roseNode, eEnum);
build(roseNode, parent, eEnum);
}
else if (stereoTypeValue.equalsIgnoreCase("datatype") || stereoTypeValue.equalsIgnoreCase("primitive"))
{
// Map to an EDataType.
//
EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
classifierName = validName(upperCaseName(objectName));
}
eDataType.setName(classifierName);
roseNode.setNode(eDataType);
setEDataTypeProperties(roseNode, eDataType);
build(roseNode, parent, eDataType);
String uml2MOFCorbaType = roseNode.getUML2MOFCorbaType();
if (uml2MOFCorbaType != null)
{
uml2MOFCorbaType = uml2MOFCorbaType.trim();
int start = uml2MOFCorbaType.indexOf("typedef ");
if (start != -1)
{
uml2MOFCorbaType = uml2MOFCorbaType.substring(8);
int end = uml2MOFCorbaType.lastIndexOf(" ");
if (end != -1)
{
uml2MOFCorbaType = uml2MOFCorbaType.substring(0, end);
}
}
if (uml2MOFCorbaType != null && uml2MOFCorbaType.length() != 0)
{
roseUtil.typeTable.put(eDataType, uml2MOFCorbaType);
}
}
}
else if (stereoTypeValue.equalsIgnoreCase("javatype"))
{
// Map to an EDataType.
//
EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType();
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
int index = objectName.lastIndexOf(".");
classifierName = validName(upperCaseName(index == -1 ? objectName : objectName.substring(index + 1)));
}
int index = objectName.lastIndexOf(".");
eDataType.setName(validName(upperCaseName(index == -1 ? objectName : objectName.substring(index + 1))));
eDataType.setInstanceClassName(objectName);
roseNode.setNode(eDataType);
setEDataTypeProperties(roseNode, eDataType);
build(roseNode, parent, eDataType);
}
else if (stereoTypeValue.equalsIgnoreCase("abstract"))
{
// Map to an EClass.
//
EClass eClass = EcoreFactory.eINSTANCE.createEClass();
allClasses.add(eClass);
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
classifierName = validName(upperCaseName(objectName));
}
eClass.setName(classifierName);
roseNode.setNode(eClass);
setEClassProperties(roseNode, eClass);
build(roseNode, parent, eClass);
}
else if (stereoTypeValue.equalsIgnoreCase("MapEntry"))
{
// Map to an EClass.
//
EClass eClass = EcoreFactory.eINSTANCE.createEClass();
allClasses.add(eClass);
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
classifierName = validName(upperCaseName(objectName));
}
eClass.setName(classifierName);
roseNode.setNode(eClass);
setEClassProperties(roseNode, eClass);
eClass.setInstanceClassName("java.util.Map$Entry");
build(roseNode, parent, eClass);
}
else if (stereoTypeValue.equalsIgnoreCase("constraint"))
{
// look for an "OCL" operation and if found, extract OCL expression from Semantics node
// first, find owning class
String x=objectName;
x = x+"";
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnrecognizedStereotype_message", new Object []{ stereoTypeValue, objectName }));
// Map to an eClass.
//
EClass eClass = EcoreFactory.eINSTANCE.createEClass();
allClasses.add(eClass);
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
classifierName = validName(upperCaseName(objectName));
}
eClass.setName(classifierName);
roseNode.setNode(eClass);
setEClassProperties(roseNode, eClass);
build(roseNode, parent, eClass);
}
}
else
{
// Map to an eClass.
//
EClass eClass = EcoreFactory.eINSTANCE.createEClass();
allClasses.add(eClass);
String classifierName = roseNode.getClassifierName();
if (classifierName == null || classifierName.length() == 0)
{
classifierName = validName(upperCaseName(objectName));
}
eClass.setName(classifierName);
roseNode.setNode(eClass);
setEClassProperties(roseNode, eClass);
build(roseNode, parent, eClass);
}
}
protected void visitOperation(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
// Map to an EOperation.
if (RoseStrings.OCL_OPERATION.equals(objectName))
return;
EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation();
String operationName = roseNode.getOperationName();
addConstraintsForOperation(roseNode, eOperation);
String rawName = operationName;
if (operationName == null || operationName.length() == 0)
{
rawName = objectName;
operationName = validName(objectName);
}
int index = rawName.lastIndexOf(">");
if (index != -1)
{
if (rawName.startsWith("<"))
{
String templateParameters = rawName.substring(1, index);
eOperation.getETypeParameters().addAll(parseTemplateParameters(templateParameters));
}
operationName = rawName.substring(index + 1).trim();
if (roseNode.getOperationName() == null || roseNode.getOperationName().length() == 0)
{
operationName = validName(operationName);
}
}
eOperation.setName(operationName);
roseNode.setNode(eOperation);
setResultType(roseNode, eOperation);
setEOperationProperties(roseNode, eOperation);
if (parent instanceof EClass)
{
// Add to an EClass
//
((EClass)parent).getEOperations().add(eOperation);
}
}
/**
* @param roseNode the node, containing the rose operation
* @param eOperation the operation the constraint should be added to
*/
private void addConstraintsForOperation(RoseNode roseNode, EOperation eOperation) {
for(RoseNode n: roseNode.getNodes()){
if(RoseStrings.ATTRIBUTE_SET.equals(Util.getType(n.getValue()))){
for(RoseNode attr: n.getNodes()){
if(RoseStrings.ATTRIBUTE.equals(Util.getType(attr.getValue()))){
String[] constraints = parseAttributesFromNode(attr, SAP2MOF_OPERATION_CODE_OCL);
if(constraints == null) {
continue;
}
StringBuilder result = new StringBuilder();
for(String clsName: constraints){
result.append(clsName);
result.append('\n');
}
result.delete(result.length()-1, result.length()); // delete last \n again
String expr = result.substring(result.indexOf("body:") + 5).trim();
//TODO ensure that the constrained name is always body and not pre/post/...
addConstraintToNamedElement("body", expr, eOperation);
}
}
}
}
}
protected void visitParameter(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
// Map to an EParameter as input parameter for operation.
//
EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter();
eParameter.setName(validName(objectName));
roseNode.setNode(eParameter);
// Do this first for better error message during setEParameterProperties.
//
if (parent instanceof EOperation)
{
((EOperation)parent).getEParameters().add(eParameter);
}
setEParameterProperties(roseNode, eParameter);
}
protected void visitInheritanceRelationship(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
String quidu = roseNode.getRoseRefId();
if (quidu != null && !quidu.equals(""))
{
quidu = quidu.substring(1, quidu.length() - 1);
}
List<String> superList = roseUtil.superTable.get(parent);
if (superList == null)
{
superList = new ArrayList<String>();
roseUtil.superTable.put(parent, superList);
}
superList.add(quidu);
superList.add(roseNode.getStereotype());
}
protected void visitClassattribute(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
// Map to EAttribute, or EEnumLiteral.
//
if (parent instanceof EEnum)
{
EEnumLiteral eEnumLiteral = ((EEnum)parent).getEEnumLiteral(objectName);
if (eEnumLiteral == null)
{
eEnumLiteral = EcoreFactory.eINSTANCE.createEEnumLiteral();
String literalName = roseNode.getAttributeName();
if (literalName == null || literalName.length() == 0)
{
literalName = validName(objectName);
}
else
{
eEnumLiteral.setLiteral(objectName);
}
eEnumLiteral.setName(literalName);
roseNode.setNode(eEnumLiteral);
if (!setEEnumLiteralProperties(roseNode, eEnumLiteral))
{
if (((EEnum)parent).getELiterals() == null)
{
eEnumLiteral.setValue(0);
}
else
{
eEnumLiteral.setValue(((EEnum)parent).getELiterals().size());
}
}
((EEnum)parent).getELiterals().add(eEnumLiteral);
}
}
else if (parent instanceof EClassifier)
{
String stereoTypeValue = null;
RoseNode stereoTypeNode = roseNode.findNodeWithKey(RoseStrings.STEREOTYPE);
if (stereoTypeNode != null)
{
stereoTypeValue = stereoTypeNode.getValue();
stereoTypeValue = stereoTypeValue.substring(1, stereoTypeValue.length() - 1);
}
if ((parent instanceof EDataType || parent instanceof EClass) && "javaclass".equalsIgnoreCase(stereoTypeValue))
{
roseUtil.typeTable.remove(parent);
((EClassifier)parent).setInstanceTypeName(objectName);
}
else if ((parent instanceof EDataType || parent instanceof EClass) && "parameter".equalsIgnoreCase(stereoTypeValue))
{
String attributeName = roseNode.getAttributeName();
if (attributeName == null || attributeName.length() == 0)
{
attributeName = objectName;
}
ETypeParameter eTypeParameter = parseTemplateParameter(attributeName);
roseNode.setNode(eTypeParameter);
((EClassifier)parent).getETypeParameters().add(eTypeParameter);
}
else if (parent instanceof EClass)
{
EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
String attributeName = roseNode.getAttributeName();
if (attributeName == null || attributeName.length() == 0)
{
attributeName = validName(objectName);
}
eAttribute.setName(attributeName);
roseNode.setNode(eAttribute);
((EClass)parent).getEStructuralFeatures().add(eAttribute);
setEAttributeProperties(roseNode, eAttribute);
if (eAttribute.getUpperBound() == 0)
{
eAttribute.setUpperBound(1);
}
// We will need to check the containment if we have to convert the EAttribute to an EReference later.
//
if (roseNode.getContainment() != null)
{
eModelElementToRoseNodeMap.put(eAttribute, roseNode);
}
// Convert to an EReference.
//
if ("reference".equals(stereoTypeValue))
{
attributesToConvert.add(eAttribute);
}
}
}
}
protected void visitAssociation(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
ref1 = null;
ref2 = null;
role1 = null;
role2 = null;
}
protected void visitRole(RoseNode roseNode, String roseNodeValue, String objectKey, String objectName, Object parent)
{
// map to EReference when is navigable
//
EReference ref = EcoreFactory.eINSTANCE.createEReference();
ref.setUpperBound(0);
String referenceName = roseNode.getReferenceName();
String rawName = referenceName;
if (referenceName == null || referenceName.length() == 0)
{
rawName = objectName;
referenceName = validName(objectName);
}
EGenericType eGenericType = null;
int index = rawName.indexOf("<");
if (index != -1)
{
eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
if (rawName.endsWith(">"))
{
String templateArguments = rawName.substring(index + 1, rawName.length() - 1);
eGenericType.getETypeArguments().addAll(parseTemplateArguments(templateArguments));
}
ref.setEGenericType(eGenericType);
referenceName = rawName.substring(0, index);
if (roseNode.getReferenceName() == null || roseNode.getReferenceName().length() == 0)
{
referenceName = validName(referenceName);
}
}
ref.setName(referenceName);
roseNode.setNode(ref);
setEReferenceProperties(roseNode, ref);
if (ref1 == null)
{
ref1 = ref;
eGenericType1 = eGenericType;
}
else if (ref2 == null)
{
ref2 = ref;
eGenericType2 = eGenericType;
}
if (role1 == null)
{
role1 = roseNode;
}
else if (role2 == null)
{
role2 = roseNode;
}
if (ref1 != null && ref2 != null && role1 != null && role2 != null)
{
String ref1Quidu = role1.getRoseRefId();
if (ref1Quidu != null && !ref1Quidu.equals(""))
{
ref1Quidu = ref1Quidu.substring(1, ref1Quidu.length() - 1);
}
String ref2Quidu = role2.getRoseRefId();
if (ref2Quidu != null && !ref2Quidu.equals(""))
{
ref2Quidu = ref2Quidu.substring(1, ref2Quidu.length() - 1);
}
//boolean ref1Navigable = role1.isNavigable();
//boolean ref2Navigable = role2.isNavigable();
boolean ref1Navigable;
boolean ref2Navigable;
ref2Navigable = role1.getSap2MofStore();
ref1Navigable = role2.getSap2MofStore();
if (ref1Navigable)
{
ref2.setEOpposite(ref1);
setEReferenceIsContainment(ref1, role1, role2);
roseUtil.refTable.put(ref1, ref2Quidu);
TableObject obj = (TableObject)roseUtil.quidTable.get(ref1Quidu);
if (obj != null)
{
roseUtil.typeTable.put(eGenericType1 == null ? ref1 : eGenericType1, obj.getName());
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeNameFor_message", new Object []{
role1.getRoseSupplier(),
ref1.getName() }));
roseUtil.typeTable.put(eGenericType1 == null ? ref1 : eGenericType1, "EObject");
}
}
else
{
if (ref1.getName() != null && ref1.getName().length() > 0)
{
EAnnotation oppositeRoleNameAnnotation = ref2.getEAnnotation(EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0);
if (oppositeRoleNameAnnotation == null)
{
oppositeRoleNameAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
oppositeRoleNameAnnotation.setSource(EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0);
ref2.getEAnnotations().add(oppositeRoleNameAnnotation);
}
else
{
oppositeRoleNameAnnotation.getDetails().clear();
}
oppositeRoleNameAnnotation.getDetails().put("Property.oppositeRoleName", ref1.getName());
}
}
if (ref2Navigable)
{
ref1.setEOpposite(ref2);
setEReferenceIsContainment(ref2, role2, role1);
roseUtil.refTable.put(ref2, ref1Quidu);
TableObject obj = (TableObject)roseUtil.quidTable.get(ref2Quidu);
if (obj != null)
{
roseUtil.typeTable.put(eGenericType2 == null ? ref2 : eGenericType2, obj.getName());
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeNameFor_message", new Object []{
role2.getRoseSupplier(),
ref2.getName() }));
roseUtil.typeTable.put(eGenericType2 == null ? ref2 : eGenericType2, "EObject");
}
}
else
{
if (ref2.getName() != null && ref2.getName().length() > 0)
{
EAnnotation oppositeRoleNameAnnotation = ref1.getEAnnotation(EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0);
if (oppositeRoleNameAnnotation == null)
{
oppositeRoleNameAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
oppositeRoleNameAnnotation.setSource(EMOFExtendedMetaData.EMOF_PACKAGE_NS_URI_2_0);
ref1.getEAnnotations().add(oppositeRoleNameAnnotation);
}
else
{
oppositeRoleNameAnnotation.getDetails().clear();
}
oppositeRoleNameAnnotation.getDetails().put("Property.oppositeRoleName", ref2.getName());
}
}
}
if (ref.getUpperBound() == 0)
{
setEReferenceDefaultMultiplicity(ref);
}
}
protected EList<EObject> getExtentFromTableObject(RoseNode roseNode)
{
String quid = roseNode.getRoseId();
if (quid != null)
{
quid = quid.substring(1, quid.length() - 1);
}
TableObject obj = (TableObject)roseUtil.quidTable.get(quid);
return obj == null ? null : obj.getContainer().getExtent();
}
protected void setEReferenceIsContainment(EReference ref, RoseNode role1, RoseNode role2)
{
boolean isAggregate = role2.isAggregate();
String containmentV = role1.getContainment();
if (isAggregate && (containmentV != null && containmentV.equalsIgnoreCase("by value")))
{
EReference opposite = ref.getEOpposite();
if (opposite != null)
{
if (opposite.getUpperBound() != 1)
{
if (bounded.contains(opposite))
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_ContainerRelationUpperBound_message", new Object []{
ref.getName(),
ref.getEOpposite().getName() }));
}
opposite.setUpperBound(1);
}
}
ref.setContainment(true);
}
}
protected void setResultType(RoseNode roseNode, EOperation eOperation)
{
/*
String name = roseNode.getResult();
for (ETypeParameter eTypeParameter : eOperation.getETypeParameters())
{
if (eTypeParameter.getName().equals(name))
{
EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
eGenericType.setETypeParameter(eTypeParameter);
eOperation.setEGenericType(eGenericType);
return;
}
}
*/
String quid = roseNode.getRoseRefId();
if (quid != null && !quid.equals(""))
{
quid = quid.substring(1, quid.length() - 1);
TableObject tableObj = (TableObject)roseUtil.quidTable.get(quid);
if (tableObj != null)
{
roseUtil.typeTable.put(eOperation, tableObj.getName());
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeIDFor_message", new Object []{ quid, eOperation.getName() }));
roseUtil.typeTable.put(eOperation, "EString");
}
}
else
{
String resultValue = getQualifiedTypeName(eOperation, roseNode.getResult());
if (resultValue != null && !resultValue.equalsIgnoreCase("void"))
{
if (!resultValue.equals(""))
{
eOperation.setEGenericType(parseTemplateArgument(resultValue));
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeNameFor_message", new Object []{
roseNode.getRoseSupplier(),
eOperation.getName() }));
roseUtil.typeTable.put(eOperation, "EString");
}
}
}
}
protected static final Pattern ANNOTATION_PATTERN = Pattern.compile("\\G\\s*((?>\\\\.|\\S)+)((?:\\s+(?>\\\\.|\\S)+\\s*+=\\s*(['\"])((?>\\\\.|.)*?)\\3)*)");
protected static final Pattern ANNOTATION_DETAIL_PATTERN = Pattern.compile("\\s+((?>\\\\.|\\S)+)\\s*+=\\s*((['\"])((?>\\\\.|.)*?)\\3)");
protected void setEModelElementProperties(RoseNode roseNode, EModelElement eModelElement)
{
String annotation = roseNode.getAnnotation();
if (annotation != null)
{
for (Matcher matcher = ANNOTATION_PATTERN.matcher(annotation); matcher.find();)
{
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.setSource(CodeGenUtil.parseString(matcher.group(1)));
for (Matcher detailMatcher = ANNOTATION_DETAIL_PATTERN.matcher(matcher.group(2)); detailMatcher.find();)
{
eAnnotation.getDetails().put(CodeGenUtil.parseString(detailMatcher.group(1)), CodeGenUtil.parseString(detailMatcher.group(4)));
}
eModelElement.getEAnnotations().add(eAnnotation);
}
}
String documentation = roseNode.getDocumentation();
if (documentation != null)
{
EcoreUtil.setDocumentation(eModelElement, documentation);
}
String constraints = roseNode.getEcoreConstraints();
if (constraints != null)
{
List<String> constraintList = new ArrayList<String>();
for (StringTokenizer stringTokenizer = new StringTokenizer(constraints); stringTokenizer.hasMoreTokens();)
{
String constraint = stringTokenizer.nextToken();
constraintList.add(constraint);
}
EcoreUtil.setConstraints(eModelElement, constraintList);
}
}
protected void setEPackageProperties(RoseNode roseNode, EPackage ePackage, String tentativeName)
{
roseNode.setNode(ePackage);
setEModelElementProperties(roseNode, ePackage);
String packageName = roseNode.getPackageName();
if (packageName == null || packageName.length() == 0)
{
packageName = validName(tentativeName);
}
ePackage.setName(packageName);
String basePackage = roseNode.getBasePackage();
String prefix = validName(upperCaseName(roseNode.getPrefix()));
String nsPrefix = roseNode.getNsPrefix() == null || roseNode.getNsPrefix().length() == 0
? (String)roseUtil.packageNameToNSNameMap.get(packageName) : roseNode.getNsPrefix();
if (nsPrefix == null || nsPrefix.length() == 0)
{
nsPrefix = packageName;
EPackage eSuperPackage = ePackage.getESuperPackage();
if (eSuperPackage != null)
{
nsPrefix = eSuperPackage.getNsPrefix() + "." + nsPrefix;
}
else if (basePackage != null && basePackage.length() != 0)
{
nsPrefix = basePackage + "." + nsPrefix;
}
}
ePackage.setNsPrefix(nsPrefix);
String nsURI = roseNode.getNsURI() == null || roseNode.getNsURI().length() == 0
? (String)roseUtil.packageNameToNSURIMap.get(packageName) : roseNode.getNsURI();
if (nsURI == null || nsURI.length() == 0)
{
if (noQualify)
{
nsURI = nsPrefix + ".ecore";
}
else
{
nsURI = "http:///" + nsPrefix.replace('.', '/') + ".ecore";
}
}
ePackage.setNsURI(nsURI);
if (prefix != null && prefix.length() == 0) {
prefix = null;
}
if (basePackage != null && basePackage.length() == 0) {
basePackage = null;
}
if (prefix != null || basePackage != null)
{
List<String> information = new ArrayList<String>();
information.add(basePackage);
information.add(prefix);
roseUtil.getEPackageToInformationMap().put(ePackage, information);
}
}
protected void setEClassProperties(RoseNode roseNode, EClass eClass)
{
setEModelElementProperties(roseNode, eClass);
String xmlName = roseNode.getXMLName();
if (xmlName != null && xmlName.length() != 0)
{
ExtendedMetaData.INSTANCE.setName(eClass, xmlName);
}
int xmlContentKind = roseNode.getXMLContentKind();
if (xmlContentKind != 0)
{
ExtendedMetaData.INSTANCE.setContentKind(eClass, xmlContentKind);
}
eClass.setAbstract(roseNode.isAbstract());
}
protected void setEDataTypeProperties(RoseNode roseNode, EDataType eDataType)
{
setEModelElementProperties(roseNode, eDataType);
String xmlName = roseNode.getXMLName();
if (xmlName != null && xmlName.length() != 0)
{
ExtendedMetaData.INSTANCE.setName(eDataType, xmlName);
}
eDataType.setSerializable(!roseNode.isAbstract());
}
protected void setEEnumProperties(RoseNode roseNode, EEnum eEnum)
{
setEModelElementProperties(roseNode, eEnum);
String xmlName = roseNode.getXMLName();
if (xmlName != null && xmlName.length() != 0)
{
ExtendedMetaData.INSTANCE.setName(eEnum, xmlName);
}
String value = roseNode.getDocumentation();
if (value != null && !value.equals(""))
{
eEnums.put(eEnum, value);
}
}
protected void populateEEnumFromDocumentation(EEnum eEnum, String documentation)
{
// process documentation info and create eEnumLiteral for each line
//
List<EEnumLiteral> eLiterals = eEnum.getELiterals();
for (StringTokenizer stringTokenizer = new StringTokenizer(documentation, ", \n\r\t"); stringTokenizer.hasMoreTokens();)
{
String literalV = stringTokenizer.nextToken();
String name = literalV;
String number = "";
int ind = literalV.indexOf("=");
if (ind != -1)
{
name = literalV.substring(0, ind);
number = literalV.substring(ind + 1, literalV.length());
}
int numberValue = 0;
if (!number.equals(""))
{
numberValue = Integer.parseInt(number);
}
else if (!eLiterals.isEmpty())
{
numberValue = eLiterals.get(eLiterals.size() - 1).getValue() + 1;
}
if (!name.equals(""))
{
EEnumLiteral lit = eEnum.getEEnumLiteral(name);
if (lit == null)
{
lit = EcoreFactory.eINSTANCE.createEEnumLiteral();
lit.setName(validName(name));
lit.setValue(numberValue);
eLiterals.add(lit);
}
else
{
lit.setValue(numberValue);
}
}
}
}
protected void setEOperationProperties(RoseNode roseNode, EOperation eOperation)
{
setETypedElementProperties(roseNode, eOperation);
eOperation.setOrdered(roseNode.isOrdered(true));
eOperation.setUnique(roseNode.isUnique(true));
String semantics = roseNode.getSemantics();
if (semantics != null && activateSemanticsTab)
{
EAnnotation eAnnotation = eOperation.getEAnnotation(GenModelPackage.eNS_URI);
if (eAnnotation == null)
{
eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.setSource(GenModelPackage.eNS_URI);
eOperation.getEAnnotations().add(eAnnotation);
}
eAnnotation.getDetails().put("body", semantics);
}
String exceptions = roseNode.getExceptions();
if (exceptions != null)
{
for (StringTokenizer stringTokenizer = new StringTokenizer(exceptions.trim(), ","); stringTokenizer.hasMoreTokens();)
{
// This handles Rose 2003 format, e.g.,
// Logical View::JavaException[40722F9D0294]
//
String exception = stringTokenizer.nextToken().trim();
if (exception.indexOf("[") != -1)
{
exception = exception.substring(0, exception.indexOf("["));
}
if (exception != null && !exception.equals(""))
{
EGenericType eGenericType = parseTemplateArgument(exception);
eOperation.getEGenericExceptions().add(eGenericType);
}
/*
String exceptionValue = getQualifiedTypeName(eOperation, exception);
if (exceptionValue != null && !exceptionValue.equals(""))
{
EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation();
eAnnotation.getReferences().add(eOperation);
eAnnotation.getDetails().put("position", Integer.toString(count++));
roseUtil.typeTable.put(eAnnotation, exceptionValue);
}
*/
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeNameFor_message", new Object []{
roseNode.getRoseSupplier(),
eOperation.getName() }));
}
}
}
String stereotype = roseNode.getStereotype();
if (stereotype != null)
{
if ("inv".equals(stereotype))
{
eOperation.setEType(EcorePackage.Literals.EBOOLEAN);
eOperation.getEParameters().clear();
EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter();
eParameter.setName("diagnostics");
eParameter.setEType(EcorePackage.Literals.EDIAGNOSTIC_CHAIN);
eOperation.getEParameters().add(eParameter);
eParameter = EcoreFactory.eINSTANCE.createEParameter();
eParameter.setName("context");
EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
eGenericType.setEClassifier(EcorePackage.Literals.EMAP);
EGenericType eGenericKeyType = EcoreFactory.eINSTANCE.createEGenericType();
eGenericKeyType.setEClassifier(EcorePackage.Literals.EJAVA_OBJECT);
eGenericType.getETypeArguments().add(eGenericKeyType);
EGenericType eGenericValueType = EcoreFactory.eINSTANCE.createEGenericType();
eGenericValueType.setEClassifier(EcorePackage.Literals.EJAVA_OBJECT);
eGenericType.getETypeArguments().add(eGenericValueType);
eParameter.setEGenericType(eGenericType);
eOperation.getEParameters().add(eParameter);
}
}
}
protected void setEAttributeProperties(RoseNode roseNode, EAttribute eAttribute)
{
eStructuralFeatures.add(eAttribute);
String quid = roseNode.getRoseRefId();
if (quid != null && !quid.equals(""))
{
quid = quid.substring(1, quid.length() - 1);
TableObject tableObj = (TableObject)roseUtil.quidTable.get(quid);
if (tableObj != null)
{
roseUtil.typeTable.put(eAttribute, tableObj.getName());
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeIDFor_message", new Object []{ quid, eAttribute.getName() }));
roseUtil.typeTable.put(eAttribute, "String");
}
}
else
{
String roseType = roseNode.getType();
if (roseType == null || roseType.equals(""))
{
roseUtil.typeTable.put(eAttribute, "String");
warning(RoseImporterPlugin.INSTANCE.getString("_UI_AttributeDoesNotDefineItsType_message", new Object []{ eAttribute.getName() }));
}
else
{
eAttribute.setEGenericType(parseTemplateArgument(roseType));
}
}
// default value
//
String initv = roseNode.getInitV();
if (initv != null && initv.length() >= 2)
{
if (initv.charAt(0) == '\'' && initv.charAt(initv.length() - 1) == '\'')
{
try
{
int i = CodeGenUtil.parseChar(initv.substring(1, initv.length() - 1));
initv = Integer.toString(i);
}
catch (IllegalArgumentException e)
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_InvalidDefaultValueForAttribute_message", new Object []{ eAttribute.getName() }));
initv = null;
}
}
else if (initv.charAt(0) == '\"' && initv.charAt(initv.length() - 1) == '\"')
{
try
{
initv = CodeGenUtil.parseString(initv.substring(1, initv.length() - 1));
}
catch (IllegalArgumentException e)
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_InvalidDefaultValueForAttribute_message", new Object []{ eAttribute.getName() }));
initv = null;
}
}
}
if (initv != null)
{
eAttribute.setDefaultValueLiteral(initv);
}
setEStructuralFeatureProperties(roseNode, eAttribute);
eAttribute.setDerived(roseNode.isDerived());
eAttribute.setTransient(roseNode.isTransient());
eAttribute.setVolatile(roseNode.isVolatile());
eAttribute.setChangeable(roseNode.isChangeable());
eAttribute.setOrdered(roseNode.isOrdered(true));
eAttribute.setUnique(roseNode.isUnique(true));
eAttribute.setUnsettable(roseNode.isUnsettable());
eAttribute.setID(roseNode.isID());
setEStructuralFeatureVisibility(roseNode, eAttribute);
}
protected void setEReferenceProperties(RoseNode roseNode, EReference eReference)
{
eStructuralFeatures.add(eReference);
eReference.setDerived(roseNode.getParent().getParent().isDerived());
setEStructuralFeatureProperties(roseNode, eReference);
// eReference.setNavigable(roseNode.isNavigable());
eReference.setTransient(roseNode.isTransient());
eReference.setVolatile(roseNode.isVolatile());
eReference.setChangeable(roseNode.isChangeable());
eReference.setResolveProxies(roseNode.isResolveProxies());
eReference.setUnsettable(roseNode.isUnsettable());
eReference.setOrdered(roseNode.isOrdered(true));
eReference.setUnique(roseNode.isUnique(true));
setEStructuralFeatureVisibility(roseNode, eReference);
}
protected void setEStructuralFeatureProperties(RoseNode roseNode, EStructuralFeature eStructuralFeature)
{
setETypedElementProperties(roseNode, eStructuralFeature);
String xmlName = roseNode.getXMLName();
if (xmlName != null && xmlName.length() != 0)
{
ExtendedMetaData.INSTANCE.setName(eStructuralFeature, xmlName);
}
int xmlFeatureKind = roseNode.getXMLFeatureKind();
if (xmlFeatureKind != 0)
{
ExtendedMetaData.INSTANCE.setFeatureKind(eStructuralFeature, xmlFeatureKind);
}
String xmlNamespace = roseNode.getXMLNamespace();
if (xmlNamespace != null && xmlNamespace.length() != 0)
{
eStructuralFeatureToXMLNamespaceMap.put(eStructuralFeature, xmlNamespace);
}
}
protected void setETypedElementProperties(RoseNode roseNode, ETypedElement eTypedElement)
{
setEModelElementProperties(roseNode, eTypedElement);
String multiplicity;
if ( eTypedElement instanceof EReference) {
multiplicity = roseNode.getRoleMultiplicity();
} else if (eTypedElement instanceof EOperation) {
multiplicity = roseNode.getAttributeValue("MOF", ROSE2MOF_RETURN_MULTIPLICITY);
if (multiplicity == null) {
multiplicity = roseNode.getStereotype(); // default
}
} else if (eTypedElement instanceof EParameter) {
multiplicity = roseNode.getAttributeValue("MOF", "uml2mof.multiplicity");
if (multiplicity == null) {
multiplicity = roseNode.getStereotype(); // default
}
} else if (eTypedElement instanceof EAttribute ){
multiplicity = roseNode.getAttributeValue("MOF", "rose2mof.multiplicity");
if (multiplicity == null) {
multiplicity = roseNode.getStereotype(); // default
}
}else {
multiplicity = roseNode.getStereotype();
}
if (multiplicity != null)
{
bounded.add(eTypedElement);
if (multiplicity.length() > 0 && Character.isLetter(multiplicity.charAt(0)) && !"n".equalsIgnoreCase(multiplicity))
return;
StringTokenizer stringTokenizer = new StringTokenizer(multiplicity, ". \n\r\t");
switch (stringTokenizer.countTokens())
{
case 1: {
String bound = stringTokenizer.nextToken();
if (bound.equals("*") || bound.equalsIgnoreCase("n"))
{
eTypedElement.setUpperBound(-1);
}
else
{
try
{
int boundValue = Integer.parseInt(bound);
if (boundValue > 0)
{
eTypedElement.setLowerBound(boundValue);
eTypedElement.setUpperBound(boundValue);
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_BadMultiplicityFor_message", new Object []{
multiplicity,
eTypedElement.getName() }));
}
}
catch (NumberFormatException exception)
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_BadMultiplicityFor_message", new Object []{
multiplicity,
eTypedElement.getName() }));
}
}
break;
}
case 2: {
String lowerBound = stringTokenizer.nextToken();
try
{
int lowerBoundValue = Integer.parseInt(lowerBound);
if (lowerBoundValue >= 0)
{
String upperBound = stringTokenizer.nextToken();
if (upperBound.equals("*") || upperBound.equalsIgnoreCase("n"))
{
eTypedElement.setLowerBound(lowerBoundValue);
eTypedElement.setUpperBound(-1);
}
else
{
int upperBoundValue = Integer.parseInt(upperBound);
if (upperBoundValue <= 0 || lowerBoundValue > upperBoundValue)
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_BadMultiplicityFor_message", new Object []{
multiplicity,
eTypedElement.getName() }));
}
else
{
eTypedElement.setLowerBound(lowerBoundValue);
eTypedElement.setUpperBound(upperBoundValue);
}
}
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_BadMultiplicityFor_message", new Object []{
multiplicity,
eTypedElement.getName() }));
}
}
catch (NumberFormatException exception)
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_BadMultiplicityFor_message", new Object []{
multiplicity,
eTypedElement.getName() }));
}
break;
}
default: {
warning(RoseImporterPlugin.INSTANCE.getString("_UI_BadMultiplicityFor_message", new Object []{
multiplicity,
eTypedElement.getName() }));
}
}
}
}
/**
* Maps the single, user-friendly Rose setting into accessor method suppression, via EcoreUtil.
*/
protected void setEStructuralFeatureVisibility(RoseNode roseNode, EStructuralFeature eStructuralFeature)
{
switch (roseNode.getVisibility())
{
case RoseNode.VISIBILITY_NONE:
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.GET, true);
if (eStructuralFeature.isChangeable() && !eStructuralFeature.isMany())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.SET, true);
}
if (eStructuralFeature.isUnsettable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET, true);
if (eStructuralFeature.isChangeable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET, true);
}
}
break;
case RoseNode.VISIBILITY_READ_ONLY:
if (eStructuralFeature.isMany())
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_InvalidReadOnlyVisibility_message", new Object []{ eStructuralFeature.getName() }));
}
else if (eStructuralFeature.isChangeable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.SET, true);
}
if (eStructuralFeature.isUnsettable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET, true);
if (eStructuralFeature.isChangeable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET, true);
}
}
break;
case RoseNode.VISIBILITY_READ_WRITE:
if (!eStructuralFeature.isChangeable() && !eStructuralFeature.isMany())
{
warning(RoseImporterPlugin.INSTANCE.getString(
"_UI_InvalidReadWriteVisibility_message",
new Object []{ eStructuralFeature.getName() }));
}
if (eStructuralFeature.isUnsettable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET, true);
if (eStructuralFeature.isChangeable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET, true);
}
}
break;
case RoseNode.VISIBILITY_READ_ONLY_UNSETTABLE:
if (eStructuralFeature.isMany())
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_InvalidReadOnlyVisibility_message", new Object []{ eStructuralFeature.getName() }));
}
else if (eStructuralFeature.isChangeable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.SET, true);
}
if (!eStructuralFeature.isUnsettable())
{
warning(RoseImporterPlugin.INSTANCE.getString(
"_UI_InvalidUnsettableVisibility_message",
new Object []{ eStructuralFeature.getName() }));
}
else if (eStructuralFeature.isChangeable())
{
EcoreUtil.setSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET, true);
}
break;
case RoseNode.VISIBILITY_READ_WRITE_UNSETTABLE:
if (!eStructuralFeature.isChangeable())
{
warning(RoseImporterPlugin.INSTANCE.getString(
"_UI_InvalidReadWriteVisibility_message",
new Object []{ eStructuralFeature.getName() }));
}
if (!eStructuralFeature.isUnsettable())
{
warning(RoseImporterPlugin.INSTANCE.getString(
"_UI_InvalidUnsettableVisibility_message",
new Object []{ eStructuralFeature.getName() }));
}
break;
default:
break;
}
}
protected boolean setEEnumLiteralProperties(RoseNode roseNode, EEnumLiteral eEnumLiteral)
{
setEModelElementProperties(roseNode, eEnumLiteral);
String value = roseNode.getInitV();
if (value != null && !value.equals(""))
{
eEnumLiteral.setValue(Integer.parseInt(value));
return true;
} else
return false;
}
protected void setEParameterProperties(RoseNode roseNode, EParameter eParameter)
{
/*
String name = roseNode.getType();
for (ETypeParameter eTypeParameter : eParameter.getEOperation().getETypeParameters())
{
if (eTypeParameter.getName().equals(name))
{
EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
eGenericType.setETypeParameter(eTypeParameter);
eParameter.setEGenericType(eGenericType);
return;
}
}
*/
setETypedElementProperties(roseNode, eParameter);
eParameter.setOrdered(roseNode.isOrdered(true));
eParameter.setUnique(roseNode.isUnique(true));
String quid = roseNode.getRoseRefId();
if (quid != null && !quid.equals(""))
{
quid = quid.substring(1, quid.length() - 1);
TableObject tableObj = (TableObject)roseUtil.quidTable.get(quid);
if (tableObj != null)
{
roseUtil.typeTable.put(eParameter, tableObj.getName());
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeIDFor_message", new Object []{
quid,
eParameter.getEOperation().getName() }));
roseUtil.typeTable.put(eParameter, "EObject");
}
}
else
{
String type = getQualifiedTypeName(eParameter, roseNode.getType());
if (type != null && !type.equals(""))
{
eParameter.setEGenericType(parseTemplateArgument(type));
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeNameFor_message", new Object []{
roseNode.getRoseSupplier(),
eParameter.getEOperation().getName() }));
roseUtil.typeTable.put(eParameter, "EObject");
}
}
}
protected void setEReferenceDefaultMultiplicity(EReference eReference)
{
if (eReference.getEOpposite() == null || !eReference.getEOpposite().isContainment())
{
eReference.setLowerBound(0);
eReference.setUpperBound(-1);
}
}
public void setEEnums()
{
for (Map.Entry<EEnum, String> entry : eEnums.entrySet())
{
EEnum eEnum = entry.getKey();
if (eEnum.getELiterals().isEmpty())
{
populateEEnumFromDocumentation(eEnum, entry.getValue());
}
}
}
protected static Comparator<Object> eClassComparator = new Comparator<Object>()
{
@Override
public int compare(Object o1, Object o2)
{
// Order first by number of features (descending) and then alphabetically (ascending)
//
EClass c1 = (EClass)(o1 instanceof EGenericType ? ((EGenericType)o1).getEClassifier() : o1);
EClass c2 = (EClass)(o2 instanceof EGenericType ? ((EGenericType)o2).getEClassifier() : o2);
int count1 = c1.getEAllAttributes().size() + c1.getEAllReferences().size();
int count2 = c2.getEAllAttributes().size() + c2.getEAllReferences().size();
if (count1 < count2)
return 1;
if (count1 > count2)
return -1;
return c1.getName().compareTo(c2.getName());
}
};
public void setSuper()
{
Map<EClass, List<EGenericType>[]> superMap = new HashMap<EClass, List<EGenericType>[]>();
for (Iterator<Object> i = roseUtil.superTable.keySet().iterator(); i.hasNext();)
{
Object subObject = i.next();
if (subObject instanceof EClass)
{
EClass eClass = (EClass)subObject;
List<EGenericType> extend = new ArrayList<EGenericType>();
List<EGenericType> unspecified = new ArrayList<EGenericType>();
List<EGenericType> mixin = new ArrayList<EGenericType>();
List<EGenericType> nonClass = new ArrayList<EGenericType>();
for (Iterator<String> j = roseUtil.superTable.get(eClass).iterator(); j.hasNext();)
{
String quid = j.next();
String stereotype = j.next();
TableObject tableObject = (TableObject)roseUtil.quidTable.get(quid);
if (tableObject != null)
{
Object superObject = tableObject.getObject();
if (superObject instanceof EClass)
{
EClass superClass = (EClass)superObject;
EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
eGenericType.setEClassifier(superClass);
if (stereotype != null)
{
int start = stereotype.indexOf("<");
if (start != -1)
{
if (stereotype.endsWith(">"))
{
String templateArguments = stereotype.substring(start + 1, stereotype.length() - 1);
eGenericType.getETypeArguments().addAll(parseTemplateArguments(templateArguments));
}
stereotype = stereotype.substring(0, start);
}
}
if (!superClass.isInterface())
{
if ("extend".equals(stereotype))
{
extend.add(eGenericType);
}
else if ("mixin".equals(stereotype))
{
mixin.add(eGenericType);
}
else
{
unspecified.add(eGenericType);
}
}
else
{
nonClass.add(eGenericType);
}
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_CannotAddSuperLinkBetween_message", new Object []{
eClass.getName(),
((ENamedElement)superObject).getName() }));
}
}
}
if (extend.size() > 1)
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_CannotSpecifyMoreThanOneExtendFor_message", new Object []{ eClass.getName() }));
}
@SuppressWarnings("unchecked")
List<EGenericType>[] lists = new List[]{extend, unspecified, mixin};
superMap.put(eClass, lists);
eClass.getEGenericSuperTypes().addAll(extend);
eClass.getEGenericSuperTypes().addAll(unspecified);
eClass.getEGenericSuperTypes().addAll(mixin);
eClass.getEGenericSuperTypes().addAll(nonClass);
/*
eClass.getESuperTypes().addAll(extend);
eClass.getESuperTypes().addAll(unspecified);
eClass.getESuperTypes().addAll(mixin);
eClass.getESuperTypes().addAll(nonClass);
*/
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString(
"_UI_CannotAddSuperLinkInvolving_message",
new Object []{ ((ENamedElement)subObject).getName() }));
}
}
sortSuper(superMap);
}
protected void sortSuper(Map<EClass, List<EGenericType>[]> superMap)
{
for (Map.Entry<EClass, List<EGenericType>[]> entry : superMap.entrySet())
{
EClass eClass = entry.getKey();
List<EGenericType>[] collections = entry.getValue();
Collections.sort(collections[0], eClassComparator);
Collections.sort(collections[1], eClassComparator);
Collections.sort(collections[2], eClassComparator);
List<EGenericType> combined = new UniqueEList<EGenericType>(collections[0]);
combined.addAll(collections[1]);
combined.addAll(collections[2]);
EList<EGenericType> eSuper = eClass.getEGenericSuperTypes();
for (ListIterator<EGenericType> ordered = combined.listIterator(); ordered.hasNext();)
{
EGenericType eSuperItem = ordered.next();
eSuper.move(ordered.previousIndex(), eSuperItem);
}
}
}
protected List<ETypeParameter> parseTemplateParameters(String templateParameters)
{
List<ETypeParameter> result = new ArrayList<ETypeParameter>();
int start = 0;
int depth = 0;
for (int i = 0, length = templateParameters.length(); i < length; ++i)
{
char character = templateParameters.charAt(i);
switch (character)
{
case ' ':
{
if (start == i)
{
++start;
}
break;
}
case '<':
{
++depth;
break;
}
case '>':
{
--depth;
break;
}
case ',':
{
if (depth == 0)
{
result.add(parseTemplateParameter(templateParameters.substring(start, i).trim()));
start = i + 1;
}
break;
}
}
}
result.add(parseTemplateParameter(templateParameters.substring(start).trim()));
return result;
}
ETypeParameter parseTemplateParameter(String templateParameter)
{
ETypeParameter eTypeParameter = EcoreFactory.eINSTANCE.createETypeParameter();
int index = templateParameter.indexOf(" extends ");
if (index == -1)
{
eTypeParameter.setName(templateParameter);
}
else
{
eTypeParameter.setName(templateParameter.substring(0, index).trim());
String bounds = templateParameter.substring(index + 9).trim();
for (StringTokenizer stringTokenizer = new StringTokenizer(bounds, "&"); stringTokenizer.hasMoreTokens(); )
{
String templateArgument = stringTokenizer.nextToken().trim();
eTypeParameter.getEBounds().add(parseTemplateArgument(templateArgument));
}
}
return eTypeParameter;
}
protected List<EGenericType> parseTemplateArguments(String templateArguments)
{
List<EGenericType> result = new ArrayList<EGenericType>();
int start = 0;
int depth = 0;
for (int i = 0, length = templateArguments.length(); i < length; ++i)
{
char character = templateArguments.charAt(i);
switch (character)
{
case ' ':
{
if (start == i)
{
++ start;
}
break;
}
case '<':
{
++depth;
break;
}
case '>':
{
--depth;
break;
}
case ',':
{
if (depth == 0)
{
result.add(parseTemplateArgument(templateArguments.substring(start, i).trim()));
start = i + 1;
}
break;
}
}
}
result.add(parseTemplateArgument(templateArguments.substring(start).trim()));
return result;
}
EGenericType parseTemplateArgument(String templateArgument)
{
EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType();
int index = 0;
int length = templateArgument.length();
if (index < length)
{
if (templateArgument.charAt(index) == '?')
{
++index;
while (index < length && Character.isWhitespace(templateArgument.charAt(index)))
{
++index;
}
if (templateArgument.indexOf("extends ") == index)
{
eGenericType.setEUpperBound(parseTemplateArgument(templateArgument.substring(index + 8).trim()));
}
else if (templateArgument.indexOf("super ") == index)
{
eGenericType.setELowerBound(parseTemplateArgument(templateArgument.substring(index + 6).trim()));
}
}
else
{
index = templateArgument.indexOf('<', index);
String name;
if (index == -1)
{
name = templateArgument;
}
else
{
name = templateArgument.substring(0, index);
eGenericType.getETypeArguments().addAll(parseTemplateArguments(templateArgument.substring(index + 1, length - 1)));
}
roseUtil.typeTable.put(eGenericType, name);
}
}
return eGenericType;
}
public void setIDs(final EObject parent, EObject child)
{
new EcoreSwitch<Object>()
{
@Override
public Object caseEPackage(EPackage ePackage)
{
return null;
}
@Override
public Object caseEClassifier(EClassifier eClassifier)
{
return null;
}
@Override
public Object caseEOperation(EOperation eOperation)
{
return null;
}
@Override
public Object caseEParameter(EParameter eParameter)
{
return null;
}
@Override
public Object caseEStructuralFeature(EStructuralFeature eStructuralFeature)
{
return null;
}
@Override
public Object caseEEnumLiteral(EEnumLiteral eEnumLiteral)
{
return null;
}
@Override
public Object defaultCase(EObject eObject)
{
for (EObject child : eObject.eContents())
{
setIDs(eObject, child);
}
return this;
}
}.doSwitch(child);
}
public void validate(EObject object)
{
new EcoreSwitch<Object>()
{
@Override
public Object caseEDataType(EDataType eDataType)
{
return validateEDataType(eDataType);
}
@Override
public Object caseEEnum(EEnum eEnum)
{
return validateEEnum(eEnum);
}
@Override
public Object caseEClass(EClass eClass)
{
return validateEClass(eClass);
}
@Override
public Object defaultCase(EObject eObject)
{
for (EObject child : eObject.eContents())
{
validate(child);
}
return this;
}
}.doSwitch(object);
}
protected Object validateEDataType(EDataType eDataType)
{
if (!(eDataType instanceof EEnum) && eDataType.getInstanceClassName() == null)
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_DatatypeNotSetFor_message", new Object []{ eDataType.getName() }));
eDataType.setInstanceClassName("java.lang.String");
}
return null;
}
protected Object validateEEnum(EEnum eEnum)
{
for (Iterator<EEnumLiteral> literals = eEnum.getELiterals().iterator(); literals.hasNext();)
{
EEnumLiteral eEnumLiteral = literals.next();
for (EEnumLiteral otherLiteral : eEnum.getELiterals())
{
if (eEnumLiteral == otherLiteral)
{
break;
}
else if (eEnumLiteral.getName().equalsIgnoreCase(otherLiteral.getName()))
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_DuplicateLiteral_message", new Object []{ eEnumLiteral.getName(), eEnum.getName() }));
literals.remove();
break;
}
}
}
return this;
}
protected Object validateEClass(EClass eClass)
{
List<EReference> oppositesToRemove = new ArrayList<EReference>();
for (Iterator<EStructuralFeature> features = eClass.getEStructuralFeatures().iterator(); features.hasNext();)
{
EStructuralFeature eStructuralFeature = features.next();
if (eStructuralFeature instanceof EAttribute)
{
EAttribute eAttribute = (EAttribute)eStructuralFeature;
// Temporary WAS/WSAD migration option.
//
if (unsettablePrimitive)
{
try
{
EDataType eDataType = eAttribute.getEAttributeType();
if (eDataType instanceof EEnum || eDataType.getInstanceClass().isPrimitive())
{
eAttribute.setUnsettable(true);
}
}
catch (Exception e)
{
// Ignore
}
}
for (EStructuralFeature otherFeature : eClass.getEAllStructuralFeatures())
{
if (eAttribute == otherFeature)
{
break;
}
else if (eAttribute.getName().equalsIgnoreCase(otherFeature.getName()))
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_DuplicateAttribute_message", new Object []{
eAttribute.getName(),
eClass.getName() }));
features.remove();
break;
}
else if (!eAttribute.getEAttributeType().isSerializable() &&
!eAttribute.isTransient() &&
!"org.eclipse.emf.ecore.util.FeatureMap$Entry".equals(eAttribute.getEAttributeType().getInstanceClassName()))
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_TheAttributeShouldBeTransient_message", new Object []{
eAttribute.getName(),
eAttribute.getEType().getName() }));
break;
}
}
}
else
{
EReference eReference = (EReference)eStructuralFeature;
EReference opposite = eReference.getEOpposite();
if (opposite != null)
{
if (opposite.eContainer() == null)
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_AnAssociationHasADanglingEnd_message", new Object []{
opposite.getName(),
eReference.getName() }));
opposite = null;
eReference.setEOpposite(null);
}
else if (opposite.isContainment())
{
// A container must be transient.
//
eReference.setTransient(true);
if (eReference.getUpperBound() != 1)
{
if (bounded.contains(eReference))
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_ContainerRelationUpperBound_message", new Object []{
opposite.getName(),
eReference.getName() }));
}
eReference.setUpperBound(1);
}
}
}
if (eReference.isTransient() && !eReference.isVolatile() && opposite != null && !opposite.isTransient()
&& opposite.isResolveProxies() && !opposite.isContainment())
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_CrossDocumentBidirectionalTransient_message", new Object []{
opposite.getName(),
eReference.getName() }));
}
for (EStructuralFeature otherFeature : eClass.getEAllStructuralFeatures())
{
if (eReference == otherFeature)
{
break;
}
else if (eReference.getName().equalsIgnoreCase(otherFeature.getName()))
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_DuplicateReference_message", new Object []{
eReference.getName(),
eClass.getName() }));
if (opposite != null)
{
oppositesToRemove.add(opposite);
}
features.remove();
break;
}
}
if (!eReference.isContainer() && "java.util.Map$Entry".equals(eReference.getEType().getInstanceClassName()))
{
if (!eReference.isContainment() || !eReference.isMany())
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_MultiplicityManyContainmentIsAssumedFor_message", new Object []{
eReference.getName(),
eClass.getName() }));
eReference.setContainment(true);
eReference.setUpperBound(-1);
}
}
}
}
for (EReference opposite : oppositesToRemove)
{
EClass oppositeEClass = opposite.getEContainingClass();
if (oppositeEClass != null)
{
oppositeEClass.getEStructuralFeatures().remove(opposite);
}
}
for (EOperation eOperation : eClass.getEOperations())
{
EClassifier opType = eOperation.getEType();
if (opType instanceof EClass && "java.util.Map$Entry".equals(opType.getInstanceClassName()))
{
if (!eOperation.isMany())
{
warning
(RoseImporterPlugin.INSTANCE.getString
("_UI_MultiplicityManyIsAssumedForOperation_message", new Object [] { eOperation.getName(), eClass.getName() }));
eOperation.setUpperBound(-1);
}
}
for (EParameter eParameter : eOperation.getEParameters())
{
EClassifier paramType = eParameter.getEType();
if (paramType instanceof EClass && "java.util.Map$Entry".equals(paramType.getInstanceClassName()))
{
if (!eParameter.isMany())
{
warning
(RoseImporterPlugin.INSTANCE.getString
("_UI_MultiplicityManyIsAssumedForParameter_message", new Object [] { eParameter.getName(), eOperation.getName(), eClass.getName() }));
eParameter.setUpperBound(-1);
}
}
}
}
if (eClass.getESuperTypes().size() > 1)
{
Iterator<EClass> superTypes = eClass.getESuperTypes().iterator();
superTypes.next();
while (superTypes.hasNext())
{
EClass superType = superTypes.next();
superFeatureLoop: for (Iterator<EStructuralFeature> superFeatures = superType.getEAllStructuralFeatures().iterator(); superFeatures.hasNext();)
{
EStructuralFeature superFeature = superFeatures.next();
for (EStructuralFeature otherFeature : eClass.getEAllStructuralFeatures())
{
if (superFeature == otherFeature)
{
break;
}
else if (superFeature.getName().equalsIgnoreCase(otherFeature.getName()))
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_DuplicateFeatureInheritance_message", new Object []{
superFeature.getName(),
eClass.getName(),
superType.getName() }));
superTypes.remove();
break superFeatureLoop;
}
}
}
}
}
if ("java.util.Map$Entry".equals(eClass.getInstanceClassName()))
{
EStructuralFeature keyFeature = eClass.getEStructuralFeature("key");
EStructuralFeature valueFeature = eClass.getEStructuralFeature("value");
if (keyFeature == null)
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_ExpectingFeatureNamedKey_message", new Object []{ eClass.getName() }));
eClass.setInstanceClassName(null);
}
if (valueFeature == null)
{
error(RoseImporterPlugin.INSTANCE.getString("_UI_ExpectingFeatureNamedValue_message", new Object []{ eClass.getName() }));
eClass.setInstanceClassName(null);
}
}
return this;
}
protected Comparator<EStructuralFeature> eStructuralFeatureComparator = new Comparator<EStructuralFeature>()
{
@Override
public int compare(EStructuralFeature o1, EStructuralFeature o2)
{
return eStructuralFeatures.indexOf(o1) - eStructuralFeatures.indexOf(o2);
}
};
public void setEReferences()
{
// process eStructuralFeatures for association end(Role)
//
for (EReference eReference : roseUtil.refTable.keySet())
{
String quid = roseUtil.refTable.get(eReference);
TableObject tableObject = (TableObject)roseUtil.quidTable.get(quid);
if (tableObject != null)
{
Object struct = tableObject.getObject();
if (struct instanceof EClass)
{
((EClass)struct).getEStructuralFeatures().add(
-1 - Collections.binarySearch(((EClass)struct).getEStructuralFeatures(), eReference, eStructuralFeatureComparator),
eReference);
}
else
{
warning(RoseImporterPlugin.INSTANCE.getString("_UI_CannotAddReference_message", new Object []{
eReference.getName(),
tableObject.getName() }));
}
}
}
for (Map.Entry<EStructuralFeature, String> entry : eStructuralFeatureToXMLNamespaceMap.entrySet())
{
EStructuralFeature eStructuralFeature = entry.getKey();
if (eStructuralFeature.eContainer() != null)
{
ExtendedMetaData.INSTANCE.setNamespace(entry.getKey(), entry.getValue());
}
}
}
public void setETypeClassifier()
{
// setup attribute and parameter type
//
for (EObject element : roseUtil.typeTable.keySet())
{
String type = roseUtil.typeTable.get(element);
int position = -1;
if (element instanceof EAnnotation)
{
position = Integer.parseInt(((EAnnotation)element).getDetails().get("position"));
element = ((EAnnotation)element).getReferences().get(0);
}
TableObject tableObj = null;
ETypeParameter resolvedETypeParameter = null;
if (type.indexOf(".") == -1)
{
String qualifier = "";
LOOP:
for (EObject parent = element.eContainer(); parent != null; parent = parent.eContainer())
{
if (parent instanceof EClass || parent instanceof EOperation)
{
for (ETypeParameter eTypeParameter :
parent instanceof EClass ? ((EClass)parent).getETypeParameters() : ((EOperation)parent).getETypeParameters())
{
if (type.equals(eTypeParameter.getName()))
{
resolvedETypeParameter = eTypeParameter;
break LOOP;
}
}
}
if (parent instanceof EPackage)
{
qualifier = ((EPackage)parent).getName() + "." + qualifier;
}
}
if (resolvedETypeParameter == null)
{
tableObj = (TableObject)roseUtil.nameTable.get(qualifier + type);
}
}
if (resolvedETypeParameter == null && tableObj == null)
{
tableObj = (TableObject)roseUtil.nameTable.get(type);
}
EClassifier eType;
if (tableObj != null && tableObj.getObject() != null && (element instanceof ETypedElement || element instanceof EGenericType))
{
// Convert attributes of with EClass type to references.
//
eType = (EClassifier)tableObj.getObject();
}
else if (resolvedETypeParameter == null)
{
// It was not found in the model class so check if primitive type.
//
eType = getBasicType(type);
if (eType == null)
{
EObject eNamedElement = element;
while (!(eNamedElement instanceof ENamedElement))
{
eNamedElement = eNamedElement.eContainer();
}
warning(RoseImporterPlugin.INSTANCE.getString("_UI_UnresolvedTypeNameFor_message", new Object []{
type,
((ENamedElement)eNamedElement).getName() }));
eType = getBasicType("EString");
}
}
else
{
// TODO So what should be the eType be now?
//
eType = getBasicType("EString");
}
EGenericType eGenericType = null;
if (element instanceof EGenericType)
{
eGenericType = (EGenericType)element;
if (resolvedETypeParameter == null)
{
eGenericType.setEClassifier(eType);
}
else
{
eGenericType.setETypeParameter(resolvedETypeParameter);
}
element = element.eContainer();
}
if (element instanceof EAttribute && eType instanceof EClass || attributesToConvert.contains(element))
{
EAttribute eAttribute = (EAttribute)element;
EReference eReference = EcoreFactory.eINSTANCE.createEReference();
RoseNode roseNode = eModelElementToRoseNodeMap.remove(eAttribute);
eReference.setName(eAttribute.getName());
eReference.setTransient(eAttribute.isTransient());
eReference.setVolatile(eAttribute.isVolatile());
eReference.setDerived(eAttribute.isDerived());
eReference.setChangeable(eAttribute.isChangeable());
eReference.setLowerBound(eAttribute.getLowerBound());
eReference.setUpperBound(eAttribute.getUpperBound());
eReference.setContainment(roseNode == null || !"by reference".equalsIgnoreCase(roseNode.getContainment()));
eReference.setResolveProxies(false);
eReference.getEAnnotations().addAll(eAttribute.getEAnnotations());
eReference.setUnsettable(eAttribute.isUnsettable());
eReference.setOrdered(eAttribute.isOrdered());
eReference.setUnique(eAttribute.isUnique());
eStructuralFeatures.set(eStructuralFeatures.indexOf(eAttribute), eReference);
EClass containingClass = eAttribute.getEContainingClass();
containingClass.getEStructuralFeatures().add(containingClass.getEStructuralFeatures().indexOf(eAttribute), eReference);
containingClass.getEStructuralFeatures().remove(eAttribute);
element = eReference;
}
else if (element instanceof EReference)
{
// Convert reference to attribute if its type is an EDataType...
//
EReference eReference = (EReference)element;
boolean convert = eType instanceof EDataType;
// ...or if it's a wildcard or group feature. Also, make it FeatureMap-typed.
//
int kind = ExtendedMetaData.INSTANCE.getFeatureKind(eReference);
if (kind == ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE || kind == ExtendedMetaData.ELEMENT_WILDCARD_FEATURE
|| kind == ExtendedMetaData.GROUP_FEATURE)
{
convert = true;
eType = EcorePackage.Literals.EFEATURE_MAP_ENTRY;
}
if (convert)
{
EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute();
eAttribute.setName(eReference.getName());
eAttribute.setTransient(eReference.isTransient());
eAttribute.setVolatile(eReference.isVolatile());
eAttribute.setDerived(eReference.isDerived());
eAttribute.setChangeable(eReference.isChangeable());
eAttribute.setLowerBound(eReference.getLowerBound());
eAttribute.setUpperBound(eReference.getUpperBound());
eAttribute.getEAnnotations().addAll(eReference.getEAnnotations());
eAttribute.setUnsettable(eReference.isUnsettable());
eAttribute.setOrdered(eReference.isOrdered());
eAttribute.setUnique(eReference.isUnique());
eStructuralFeatures.set(eStructuralFeatures.indexOf(eReference), eAttribute);
EClass containingClass = eReference.getEContainingClass();
if (containingClass != null)
{
containingClass.getEStructuralFeatures().add(containingClass.getEStructuralFeatures().indexOf(eReference), eAttribute);
containingClass.getEStructuralFeatures().remove(eReference);
}
element = eAttribute;
}
}
if (element instanceof EDataType)
{
if (eGenericType == null)
{
((EDataType)element).setInstanceClassName(eType.getInstanceClassName());
}
}
else if (position != -1)
{
List<EClassifier> exceptions = ((EOperation)element).getEExceptions();
if (!exceptions.contains(eType))
{
if (position < exceptions.size())
{
exceptions.add(position, eType);
}
else
{
exceptions.add(eType);
}
}
}
else if (element instanceof ETypedElement)
{
if (eGenericType != null)
{
if (!(element instanceof EOperation) || !((EOperation)element).getEGenericExceptions().contains(eGenericType))
{
((ETypedElement)element).setEGenericType(eGenericType);
}
}
else
{
((ETypedElement)element).setEType(eType);
}
if (element instanceof EStructuralFeature)
{
EStructuralFeature eStructuralFeature = (EStructuralFeature)element;
if ("".equals(eStructuralFeature.getName()))
{
eStructuralFeature.setName(eType.getName());
}
}
}
}
}
protected EClassifier getBasicType(String value)
{
if (value.equals("boolean") || value.equalsIgnoreCase("eboolean"))
return EcorePackage.Literals.EBOOLEAN;
else if (value.equalsIgnoreCase("boolean") || value.equalsIgnoreCase("ebooleanobject"))
return EcorePackage.Literals.EBOOLEAN_OBJECT;
else if (value.equalsIgnoreCase("string") || value.equalsIgnoreCase("estring"))
return EcorePackage.Literals.ESTRING;
else if (value.equalsIgnoreCase("char") || value.equalsIgnoreCase("echar"))
return EcorePackage.Literals.ECHAR;
else if (value.equalsIgnoreCase("character") || value.equalsIgnoreCase("echaracterobject"))
return EcorePackage.Literals.ECHARACTER_OBJECT;
else if (value.equals("double") || value.equalsIgnoreCase("edouble") || value.equalsIgnoreCase("currency"))
return EcorePackage.Literals.EDOUBLE;
else if (value.equalsIgnoreCase("double") || value.equalsIgnoreCase("edoubleobject"))
return EcorePackage.Literals.EDOUBLE_OBJECT;
else if (value.equalsIgnoreCase("int") || value.equalsIgnoreCase("eint"))
return EcorePackage.Literals.EINT;
else if (value.equalsIgnoreCase("integer") || value.equalsIgnoreCase("eintegerobject"))
return EcorePackage.Literals.EINTEGER_OBJECT;
else if (value.equals("long long") || value.equals("long") || value.equalsIgnoreCase("elong"))
return EcorePackage.Literals.ELONG;
else if (value.equalsIgnoreCase("long") || value.equalsIgnoreCase("elongobject"))
return EcorePackage.Literals.ELONG_OBJECT;
else if (value.equals("float") || value.equalsIgnoreCase("efloat") || value.equalsIgnoreCase("single"))
return EcorePackage.Literals.EFLOAT;
else if (value.equalsIgnoreCase("float") || value.equalsIgnoreCase("efloatobject"))
return EcorePackage.Literals.EFLOAT_OBJECT;
else if (value.equals("short") || value.equalsIgnoreCase("eshort"))
return EcorePackage.Literals.ESHORT;
else if (value.equalsIgnoreCase("short") || value.equalsIgnoreCase("eshortobject"))
return EcorePackage.Literals.ESHORT_OBJECT;
else if (value.equals("byte") || value.equalsIgnoreCase("ebyte"))
return EcorePackage.Literals.EBYTE;
else if (value.equals("byte[]") || value.equalsIgnoreCase("ebytearray") || value.equalsIgnoreCase("ebyte[]"))
return EcorePackage.Literals.EBYTE_ARRAY;
else if (value.equalsIgnoreCase("byte") || value.equalsIgnoreCase("ebyteObject"))
return EcorePackage.Literals.EBYTE_OBJECT;
else if (value.equalsIgnoreCase("ebigdecimal"))
return EcorePackage.Literals.EBIG_DECIMAL;
else if (value.equalsIgnoreCase("ebiginteger"))
return EcorePackage.Literals.EBIG_INTEGER;
else if (value.equalsIgnoreCase("edate"))
return EcorePackage.Literals.EDATE;
else if (value.equalsIgnoreCase("eobject"))
return EcorePackage.Literals.EOBJECT;
else if (value.equalsIgnoreCase("efeaturemapentry"))
return EcorePackage.Literals.EFEATURE_MAP_ENTRY;
else
return null;
}
public void createEPackageForRootClasses(EList<EObject> extent, RoseNode roseNode, String packageName)
{
ArrayList<EObject> list = new ArrayList<EObject>();
for (EObject eObject : extent)
{
if (!(eObject instanceof EPackage))
{
list.add(eObject);
}
}
if (!list.isEmpty())
{
EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage();
addDelegateAnnotation(ePackage);
setEPackageProperties(roseNode, ePackage, packageName.toLowerCase());
extent.add(ePackage);
for (Iterator<EObject> i = list.iterator(); i.hasNext();)
{
EClassifier eClassifier = (EClassifier)i.next();
ePackage.getEClassifiers().add(eClassifier);
extent.remove(eClassifier);
}
}
}
private void addDelegateAnnotation(EPackage packg){
EcoreUtil.setAnnotation(packg, ECORE_NS_URI, INVOCATION_DELEGATES, DELEGATE_URI);
EcoreUtil.setAnnotation(packg, ECORE_NS_URI, VALIDATION_DELEGATES, DELEGATE_URI);
}
protected void build(RoseNode roseNode, Object parent, ENamedElement eNamedElement)
{
String quid = roseNode.getRoseId();
if (quid != null && !quid.equals(""))
{
quid = quid.substring(1, quid.length() - 1);
}
TableObject tableObj = (TableObject)roseUtil.quidTable.get(quid);
if (tableObj != null)
{
tableObj.setObject(eNamedElement);
}
if (parent instanceof EPackage)
{
((EPackage)parent).getEClassifiers().add((EClassifier)eNamedElement);
}
else if (parent instanceof EList<?>)
{
@SuppressWarnings("unchecked")
EList<ENamedElement> namedElements = (EList<ENamedElement>)parent;
namedElements.add(eNamedElement);
}
}
protected String upperCaseName(String name)
{
return name != null && name.length() > 0 && Character.isLowerCase(name.charAt(0)) ? Character.toUpperCase(name.charAt(0))
+ name.substring(1) : name;
}
protected String validName(String name)
{
return CodeGenUtil.validJavaIdentifier(name);
}
protected void warning(String message)
{
System.err.println("-->Warning: " + message);
roseUtil.addDiagnostic(new BasicDiagnostic(Diagnostic.WARNING, RoseImporterPlugin.getPlugin().getBundle().getSymbolicName(), 0, message, null));
}
protected void error(String message)
{
System.err.println("-->Error: " + message);
roseUtil.addDiagnostic(new BasicDiagnostic(Diagnostic.ERROR, RoseImporterPlugin.getPlugin().getBundle().getSymbolicName(), 0, message, null));
}
protected String getQualifiedTypeName(ETypedElement typedElement, String type)
{
return getQualifiedTypeName((EModelElement)typedElement, type);
}
protected String getQualifiedTypeName(EModelElement eModelElement, String type)
{
// try to retrieve the fully qualified name of the specified type...
if (null == type || type.length() == 0 || "void".equals(type))
return type;
String qualifiedType = type;
// convert to dot-separated format if necessary...
if (qualifiedType.indexOf("::") != -1)
{
StringTokenizer st = new StringTokenizer(qualifiedType, "::");
if (st.hasMoreTokens())
{
st.nextToken();
}
StringBuffer stringBuffer = new StringBuffer();
while (st.hasMoreTokens())
{
// remove garbage characters...
stringBuffer.append(st.nextToken().replace('"', ' ').replace('[', ' ').replace(']', ' ').trim());
if (st.hasMoreTokens())
{
stringBuffer.append(".");
}
}
qualifiedType = stringBuffer.toString();
}
// qualify type name if not already qualified...
if (qualifiedType.indexOf('.') == -1 && eModelElement != null)
{
String qualifier = "";
for (EObject parent = eModelElement.eContainer(); null != parent; parent = parent.eContainer())
{
if (parent instanceof EPackage)
{
qualifier = ((EPackage)parent).getName() + "." + qualifier;
}
}
qualifiedType = qualifier + qualifiedType;
}
if (!qualifiedType.equals(type) && !roseUtil.nameTable.containsKey(qualifiedType))
{
qualifiedType = type;
}
return qualifiedType;
}
}